package control;

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.EnumMap;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import model.Cases;
import model.Event;
import model.User;

/**
 * The class is responsible for listening to action events and calling different
 * methods according to which button is pushed
 * <p>
 * @author Tim
 * @version 2014-05-25
 */
public class DetailedPanelListener implements ActionListener {

    private final view.MainFrame view;
    private final model.MiljoBoven model;
    private final view.DetailedPanel detailedPanel;
    private model.Cases activeCase;

    /**
     * Constructor for class DetailedPanelListener
     *
     * @param view The main view object
     * @param model The main model object
     * @param detailedPanel The object the class is a listener to
     */
    public DetailedPanelListener(view.MainFrame view, model.MiljoBoven model, view.DetailedPanel detailedPanel) {
        this.view = view;
        this.model = model;
        this.detailedPanel = detailedPanel;
    }

        /**
     * Enum containing individual action types.
     */
    public enum Type {

        CANCEL("Avbryt"),
        SAVE("Spara ändringar"),
        NEW_CASE("Skapa nytt fall"),
        NEW_EVENT("Registrera ny händelse"),
        ADD_FILE("Bifoga fil"),
        OPEN_FILE("Öppna bilaga");

        private final String actionNameSE;

        private Type(String actionNameSE) {
            this.actionNameSE = actionNameSE;
        }

        @Override
        public String toString() {
            return actionNameSE;
        }

        /**
         * Returns an enum if the parameter matches any of the custom enum
         * names. Otherwise calls method .valueOf().
         * <p>
         * @param actionNameSE The name of the action/button
         * @return Type if found
         */
        public static Type valueFromCustomString(String actionNameSE) {
            for (Type type : Type.values()) {
                if (type.toString().equals(actionNameSE)) {
                    return type;
                }
            }
            return Type.valueOf(actionNameSE);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (Type.valueFromCustomString(e.getActionCommand())) {
            case CANCEL:
                view.showMainPanel();
                activeCase = null;
                break;
            case SAVE:
                model.updateCase(detailedPanel.getCaseData());
                model.saveCases();
                model.setTableRowData();
                view.getMainPanel().setTableData(model.setTableRowData());
                view.showMainPanel();
                break;
            case NEW_CASE:
                model.updateCase(detailedPanel.getCaseData());
                model.addCurrentCase();
                model.saveCases();
                view.getMainPanel().setTableData(model.setTableRowData());
                view.getDetailedPanel().saveCaseMessage();

                
                model.createNewCase();

                EnumMap<Cases.Field, Object> caseDataMap = new EnumMap<>(Cases.Field.class);
                ArrayList<EnumMap<Event.Field, Object>> eventList = new ArrayList<>();
                EnumMap<Cases.Field, Collection> fieldChoices = new EnumMap<>(Cases.Field.class);
                fieldChoices.put(Cases.Field.RESPONSIBLE_DEPARTMENT, Cases.Field.RESPONSIBLE_DEPARTMENT.getChoices());
                fieldChoices.put(Cases.Field.STATUS, Cases.Field.STATUS.getChoices());
                caseDataMap.put(Cases.Field.CASE_ID, model.getCaselist().size() + 1);
                view.getDetailedPanel().updatePanel(true, caseDataMap, eventList, model.getCurrentUser().getUserType(), fieldChoices, model.getCaselist().size() + 1, User.getEditingRights());

                break;
            case NEW_EVENT:

                String comment = detailedPanel.getEventData().get(Event.Field.EVENT_DESCRIPTION).getText();
                File newFile = new File(detailedPanel.getEventData().get(Event.Field.EVENT_FILE).getText());

                if (comment.isEmpty()) {
                    JOptionPane.showMessageDialog(null, "Kommentaren kan inte vara tom", "Felmeddelande", JOptionPane.ERROR_MESSAGE);
                } else {
                    Event newEvent = new Event(model.getEventsForCase().size()+1, new Date(), comment, newFile);
                    System.out.println(comment + "+" + newFile);
                    model.addEvent(newEvent);
                    model.saveCases();

                    // Clear event input fields
                    detailedPanel.getEventData().get(Event.Field.EVENT_DESCRIPTION).setText("");
                    detailedPanel.getEventData().get(Event.Field.EVENT_FILE).setText("");
                }

                // ArrayList<Event> -> ArrayList<EnumMap>
                ArrayList<EnumMap<Event.Field, Object>> events = new ArrayList<>();
                for (Event event : model.getEventsForCase()) {
                    EnumMap<Event.Field, Object> map = new EnumMap<>(model.Event.Field.class);
                    map.put(Event.Field.EVENT_ID, event.getId());
                    map.put(Event.Field.EVENT_DATE, event.getDate());
                    map.put(Event.Field.EVENT_DESCRIPTION, event.getComment());
                    map.put(Event.Field.EVENT_FILE, event.getFile());
                    events.add(map);
                }
                detailedPanel.updateEvents(events);

                break;
            case ADD_FILE:
                JFileChooser chooser = new JFileChooser();
                int returnVal = chooser.showOpenDialog(null);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    detailedPanel.addFile(chooser.getSelectedFile());
                }
                break;
            case OPEN_FILE:
                JTable table = (JTable) e.getSource();
                File file = (File) table.getValueAt(table.getSelectedRow(), 3);
                try {
                    Desktop.getDesktop().open((file));
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(null, "Filen kunde inte öppnas", "Oj, ett fel har uppstått", JOptionPane.ERROR_MESSAGE);
                } catch (IllegalArgumentException ex) {
                    JOptionPane.showMessageDialog(null, "Filen kunde inte hittas", "Oj, ett fel har uppstått", JOptionPane.ERROR_MESSAGE);
                }
                break;
            default:
                System.out.println("Default action");
        }
    }
}
